function ABDebug(show, id) {
    /*
     *       Debug module
     * */
    var debug = false;
    var LOG;

    function fillLeadZero(val) {
        return (val < 10 ? '0' : '') + val
    }

    function timeToString(val) {
        return fillLeadZero(val.getHours()) + ':' + fillLeadZero(val.getMinutes()) + ':' + fillLeadZero(val
                .getSeconds());
    }

    function createEl(name, attrs, childs) {
        var el = document.createElement(name);
        for (var i = 0; i < attrs.length; i++) el.setAttribute(attrs[i][0], attrs[i][1]);
        for (var j = 0; j < childs.length; j++) el.appendChild(childs[j]);
        return el;
    }

    function logImpl(str, dumpobj) {
        if (debug) {
            var s = timeToString(new Date()) + ' ' + dump(str, dumpobj) + '\n' + $(LOG)[0].value;
            $(LOG)[0].value = s.substr(0, Math.min(30000, s.length));
        }
    }

    function objString(obj) {
        return Object.prototype.toString.apply(obj);
    }

    function funcString(func) {
        var s = '' + func;
        return s.substring(0, s.indexOf(')') + 1);
    }

    function dump(obj, dumpobj) {
        try {
            if (undefined === obj || null === obj) return '' + obj;
            var type = typeof(obj);
            if (type == 'boolean' || type == 'number' || type == 'string') return '' + obj;
            if (type == 'function') return funcString(obj);

            var prefix = objString(obj);
            var name = prefix.substring(8, prefix.length - 1);
            var str = '';

            if (name == 'Element') return dumpNode(obj);
            else {
                for (var i in obj) //	for (var i = 0; i < obj.length; i++)
                {
                    str += i + ':';
                    if (typeof(obj[i]) == 'function')  str += funcString(obj[i]);
                    else if (typeof(obj[i]) == 'object') str += dumpobj ? dump(obj[i], dumpobj) : objString(obj[i]);
                    else str += obj[i];
                    str += ', ';
                }
            }

            return prefix + ' {' + str + '}';
        }
        catch (e) {
            return 'Exception: ' + e.message + ' - ' + obj;
        }
    }

    function dumpNode(node) {
        if (undefined === node || null === node) return '' + node;
//			var str = node.nodeName+'('+node.nodeType+')='+node.nodeValue+', childs='+node.childNodes.length;
        var str = node.nodeName + ', type=' + node.nodeType + ', childs=' + node.childNodes.length;
        if (node.nodeType == 1) {
            for (var i = 0; i < node.attributes.length; i++) {
                str += ' ' + node.attributes[i].nodeName + '=' + node.attributes[i].nodeValue;
            }
        }
        return objString(node) + ' {' + str + '}';
    }

    function initDebug(id, show) {
        if (!id) id = 'body';
        debug = true;
        //if (!debug) return;
/*
        LOG = createEl('textarea', [
            ["cols", "120"],
            ['rows', '8'],
            ['WRAP','OFF']
        ], []);
        $(LOG).prependTo(id);
*/
//	    LOG = $('<div><textarea cols="120" rows="8" wrap=off></textarea></div>').prependTo(id)[0];
	    LOG = $('<textarea cols="120" rows="8" wrap=off></textarea>');
	    var wrap = $('<div></div>').prependTo(id)[0]
	    LOG.appendTo(wrap);
        $(LOG).dblclick(function () {
            $(LOG)[0].value = '';
        });
        window.onerror = function (message, url, lineNo) {
            logImpl('Error: ' + message + '\n Url: ' + url + '\n Line Number: ' + lineNo);
	        $(LOG).show();
	        if ($.unblockUI) $.unblockUI();
            return false;
        };
        if (!show) $(LOG).hide();
    }

    initDebug(id, show);
    this.log = ABDebug.log = window.log = logImpl;
    this.console = ABDebug.console = $(LOG);//function() {return $(LOG);}
	$(window.document).keydown(function(e){
		if (e.keyCode == 192 & e.ctrlKey) ABDebug.console.toggle();
	});

}